package com.demo.springboot.resttemplate.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.demo.springboot.resttemplate.entity.HufuResponseVo;
import com.demo.springboot.resttemplate.entity.HufuUserVo;
import com.demo.springboot.resttemplate.entity.HufuTokenVo;
import com.huge.common.util.EncryptUtil;
import com.huge.common.util.RestTemplateUtil;
import com.huge.common.util.StringUtil;
import com.huge.common.util.TimeUtil;
import com.huge.common.vo.ResponseResult;
import com.huge.user.api.vo.UserDeleteVo;
import com.huge.user.api.vo.UserLoginVo;
import com.huge.user.api.vo.UserReadableVo;
import com.huge.user.api.vo.UserRegisterVo;
import com.demo.springboot.resttemplate.config.PropertyConfig;
import com.demo.springboot.resttemplate.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * RestTemplate client
 * @author WangGang
 * @date 2021/10/27
 */
@RestController
@RequestMapping("client")
public class ClientController {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private PropertyConfig propertyConfig;

    /**
     * add user
     * @author WangGang
     * @date 2021/10/27
     */
    @PostMapping("addUser")
    public ResponseEntity<User> addUser(@RequestBody User user) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("token","aa11bb22");
        // 封装参数和头信息
        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(user),httpHeaders);
        String url = "http://localhost:8090/server/addUser";
        return restTemplate.postForEntity(url, httpEntity, User.class);
    }

    /**
     * add user by util
     * @author WangGang
     * @date 2021/10/27
     */
    @PostMapping("addUserByUtil")
    public ResponseEntity<User> addUserByUtil(@RequestBody User user) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("token","aa11bb22");
        // 封装参数和头信息
        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(user),httpHeaders);
        String url = "http://localhost:8090/server/addUser";
        return RestTemplateUtil.post(url, httpEntity, User.class);
    }

    @PostMapping("addUserByForm")
    public ResponseEntity<User> addUserByForm(User user, HttpServletRequest request) {
        String token=request.getHeader("token");
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        httpHeaders.add("token",token);
        // 封装参数和头信息
        user.setToken(token);
        MultiValueMap params=new LinkedMultiValueMap();
        params.add("age",user.getAge());
        params.add("name",user.getName());
        params.add("id",user.getId());
        params.add("token",user.getToken());
        HttpEntity<MultiValueMap> httpEntity = new HttpEntity(params,httpHeaders);
        String url = propertyConfig.getUserServer()+propertyConfig.getUrlAddUserByForm();
        return RestTemplateUtil.post(url, httpEntity, User.class);
    }

    /**
     * change password
     * @author WangGang
     * @date 2021/10/27
     */
    @PutMapping("changePassword")
    public ResponseResult<String> changePassword(@RequestBody UserLoginVo accountLoginVo) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("token",propertyConfig.getUserToken());
        // 封装参数和头信息
        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(accountLoginVo),httpHeaders);
        String url = propertyConfig.getUserServer()+propertyConfig.getUrlChangePassword();
        ResponseEntity<JSONObject> responseEntity= RestTemplateUtil.put(url, httpEntity,JSONObject.class);

        return StringUtil.json2ResponseResult(responseEntity.getBody().toString(),String.class);
    }

    /**
     * delete user
     * @author WangGang
     * @date 2021/11/5
     */
    @PutMapping("deleteUser")
    public ResponseResult<String> deleteUser(@RequestBody UserDeleteVo userVo) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("token",propertyConfig.getUserToken());
        // 封装参数和头信息
        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(userVo),httpHeaders);
        String url = propertyConfig.getUserServer()+propertyConfig.getUrlDeleteUser();
        ResponseEntity<JSONObject> responseEntity= RestTemplateUtil.put(url, httpEntity,JSONObject.class);

        return StringUtil.json2ResponseResult(responseEntity.getBody().toString(),String.class);
    }

    /**
     * exchange-get with param
     * @param name 姓名
     * @author WangGang
     * @date 2021/10/27
     */
    @GetMapping("exchangeGetWithParam")
    public ResponseEntity<String> exchangeGetWithParam(String name){

        HttpHeaders requestHeader = new HttpHeaders();
        requestHeader.add("token", "wetyuigyihjj");
        requestHeader.add("charset", "UTF-8");
        requestHeader.setContentType(MediaType.APPLICATION_JSON);

//        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
//        requestBody.add("name", name);
        Map<String, String> requestBody=new HashMap();
        requestBody.put("name", name);

        HttpEntity<Map>  httpEntity = new HttpEntity(null, requestHeader);

        return restTemplate.exchange("http://localhost:8090/server/getUserByName?name={name}", HttpMethod.GET, httpEntity,String.class,requestBody);
    }

    /**
     * exchange-post
     * @author WangGang
     * @date 2021/10/27
     */
    @PostMapping("exchangePost")
    public ResponseEntity<JSONObject> exchangePost(HufuUserVo userVo,HttpServletRequest request) {
//        HttpHeaders httpHeaders = new HttpHeaders();
//        // 设置请求类型
//        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
//        httpHeaders.add("token","aa11bb22");
//        // 封装参数和头信息
//        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(user),httpHeaders);
//        String url = "http://localhost:8090/server/addUser";
//        return restTemplate.exchange(url, HttpMethod.POST,httpEntity, User.class);
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        httpHeaders.add("accessToken",request.getHeader("accessToken"));

//        Map params=new HashMap();
//        params.put("loginName",userVo.getLoginName());
//        params.put("password",userVo.getPassword());
//        params.put("organizationIds",userVo.getOrganizationIds());
//        params.put("name",userVo.getName());
//        // 封装参数和头信息
//        HttpEntity<Map> httpEntity = new HttpEntity(params,httpHeaders);
        MultiValueMap params=new LinkedMultiValueMap();
        params.add("loginName",userVo.getLoginName());
        params.add("password",userVo.getPassword());
        params.add("organizationIds",userVo.getOrganizationIds());
        params.add("name",userVo.getName());

        // 封装参数和头信息
        HttpEntity<MultiValueMap> httpEntity = new HttpEntity(null,httpHeaders);
        String url = String.format("http://admin-dev.tiger-sec.cn/api/user/save?loginName=%s&password=%s&name=%s&organizationIds=%d",userVo.getLoginName(),userVo.getPassword(),userVo.getName(),1405769836601987073l);
        ResponseEntity<JSONObject> res= restTemplate.exchange(url, HttpMethod.POST,httpEntity, JSONObject.class);

        return res;
    }

    /**
     * 
     * get property
     * @author WangGang
     * @date 2021/10/28
     */
    @GetMapping("getProperty")
    public String getProperty() {
        return propertyConfig.toString();
    }

    @GetMapping("getTokenVo")
    public ResponseEntity<HufuTokenVo> getTokenVo(){
        HufuTokenVo hufuTokenVo =new HufuTokenVo();
        hufuTokenVo.setClientId(propertyConfig.getHufuClientId());
        hufuTokenVo.setTimestamp(TimeUtil.getTimestamp(LocalDateTime.now()));
        hufuTokenVo.setSign(EncryptUtil.generateHufuSign(hufuTokenVo.getClientId(),propertyConfig.getHufuClientSecret(), hufuTokenVo.getTimestamp()));
        hufuTokenVo.setClientSecret(propertyConfig.getHufuClientSecret());

        return ResponseEntity.ok(hufuTokenVo);
    }

    /**
     * get user
     * @author WangGang
     * @date 2021/10/27
     */
    @GetMapping("getUser")
    public ResponseEntity<String> getUser(){
        return restTemplate.getForEntity("http://localhost:8090/server/getUser", String.class);
    }

    /**
     * get user by util
     * @author WangGang
     * @date 2021/10/27
     */
    @GetMapping("getUserByUtil")
    public ResponseEntity<String> getUserByUtil(){
        return RestTemplateUtil.get("http://localhost:8090/server/getUser", String.class);
    }

    /**
     * get user by name
     * @param name 姓名
     * @author WangGang
     * @date 2021/10/27
     */
    @GetMapping("getUserByName")
    public ResponseEntity getUserByName(String name){
        return restTemplate.getForEntity("http://localhost:8090/server/getUserByName?name={name}", String.class,name);
    }

    /**
     * get user by name with util
     * @param name 姓名
     * @author WangGang
     * @date 2021/10/27
     */
    @GetMapping("getUserByNameWithUtil")
    public ResponseEntity getUserByNameWithUtil(String name){
        return RestTemplateUtil.get("http://localhost:8090/server/getUserByName?name={name}", String.class,name);
    }

    /**
     * get user with header
     * @author WangGang
     * @date 2021/10/27
     */
    @GetMapping("getUserWithHeader")
    public ResponseEntity<String> getUserWithHeader(String name){

        HttpHeaders headers = new HttpHeaders();
        headers.add("token", "wetyuigyihjj");
        headers.add("charset", "UTF-8");
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map map=new HashMap();
        map.put("name",name);

        HttpEntity httpEntity = new HttpEntity(null, headers);

        return restTemplate.exchange("http://localhost:8090/server/getUserByName?name={name}", HttpMethod.GET, httpEntity,String.class,map);
    }

    /**
     * get user with header by util
     * @author WangGang
     * @date 2021/10/27
     */
    @GetMapping("getUserWithHeaderByUtil")
    public ResponseEntity<String> getWithHeaderByUtil(String name){

        HttpHeaders headers = new HttpHeaders();
        headers.add("token", "wetyuigyihjj");
        headers.add("charset", "UTF-8");
        headers.setContentType(MediaType.APPLICATION_JSON);

//        HttpEntity httpEntity = new HttpEntity<>(null, headers);

        Map map=new HashMap();
        map.put("name",name);

//        return restTemplate.exchange("http://localhost:8090/server/user", HttpMethod.GET, httpEntity,String.class);
        return RestTemplateUtil.get("http://localhost:8090/server/getUserByName?name={name}", headers,String.class,map);
    }

    @GetMapping("hufuTokenGet")
    public HufuResponseVo<HufuTokenVo> hufuTokenGet() {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HufuTokenVo hufuTokenVo =new HufuTokenVo();
        hufuTokenVo.setClientId(propertyConfig.getHufuClientId());
        hufuTokenVo.setTimestamp(TimeUtil.getTimestamp(LocalDateTime.now()));
        hufuTokenVo.setSign(EncryptUtil.generateHufuSign(hufuTokenVo.getClientId(),propertyConfig.getHufuClientSecret(), hufuTokenVo.getTimestamp()));
        LinkedMultiValueMap<String,Object> requestForm=new LinkedMultiValueMap();
        requestForm.add("clientId", hufuTokenVo.getClientId());
        requestForm.add("timestamp", hufuTokenVo.getTimestamp());
        requestForm.add("sign", hufuTokenVo.getSign());
        HttpEntity<LinkedMultiValueMap<String, Object>> request = new HttpEntity<>(requestForm, httpHeaders);
        String url = propertyConfig.getHufuHost()+propertyConfig.getHufuUrlGetToken();
        ResponseEntity<JSONObject> res=RestTemplateUtil.post(url, request, JSONObject.class);

        return json2HufuResponseVo(res.getBody().toString(), HufuTokenVo.class);

    }

    @DeleteMapping("hufuUserDelete")
    public HufuResponseVo<String> hufuUserDelete(long userId, HttpServletRequest request) {
        String accessToken = request.getHeader("accessToken");
        HttpHeaders headers = new HttpHeaders();
        headers.add("accessToken", accessToken);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        String url = propertyConfig.getHufuHost()+propertyConfig.getHufuUrlUserDelete()+userId;
        ResponseEntity<JSONObject> res= RestTemplateUtil.delete(url, headers,JSONObject.class, new HashMap());

        return json2HufuResponseVo(res.getBody().toString(), String.class);

    }

    @GetMapping("hufuUserGet")
    public HufuResponseVo<HufuUserVo> hufuUserGet(long userId, HttpServletRequest request) {
        String accessToken = request.getHeader("accessToken");
        HttpHeaders headers = new HttpHeaders();
        headers.add("accessToken", accessToken);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        String url = propertyConfig.getHufuHost()+propertyConfig.getHufuUrlUserGet()+userId;
        ResponseEntity<JSONObject> res= RestTemplateUtil.get(url, headers,JSONObject.class, new HashMap());

        return json2HufuResponseVo(res.getBody().toString(), HufuUserVo.class);

    }

    @PostMapping("hufuUserSave")
    public HufuResponseVo<HufuUserVo> hufuUserSave(HufuUserVo userVo, HttpServletRequest request) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        httpHeaders.add("accessToken",request.getHeader("accessToken"));

        // 封装参数和头信息
        HttpEntity<MultiValueMap> httpEntity = new HttpEntity(null,httpHeaders);
        String url=propertyConfig.getHufuHost()+propertyConfig.getHufuUrlUserSave();
        String params=String.format("?loginName=%s&password=%s&name=%s&organizationIds=%d",userVo.getLoginName(),userVo.getPassword(),userVo.getName(),1405769836601987073l);
        url=String.format("%s%s",url,params);
        ResponseEntity<JSONObject> res= restTemplate.exchange(url, HttpMethod.POST,httpEntity, JSONObject.class);

        return json2HufuResponseVo(res.getBody().toString(), HufuUserVo.class);

    }

    @GetMapping("isValidToken")
    public ResponseResult<Boolean> isValidToken(String token){
        Map<String,String> map=new HashMap<>();
        map.put("token",token);

        String url=propertyConfig.getUserServer()+propertyConfig.getUrlIsValidToken()+"?token={token}";
        ResponseEntity<JSONObject> responseEntity= RestTemplateUtil.get(url, JSONObject.class,map);

        return StringUtil.json2ResponseResult(responseEntity.getBody().toString(),Boolean.class);
    }

    /**
     * login
     * @param username 用户名
     * @param password 密码
     * @author WangGang
     * @date 2021/10/29
     */
    @GetMapping("login")
    public ResponseResult<UserReadableVo> login(String username, String password){
        Map<String,String> map=new HashMap<>();
        map.put("username",username);
        map.put("password",password);

        String url=propertyConfig.getUserServer()+propertyConfig.getUrlLogin()+"?username={username}&password={password}";
        ResponseEntity<JSONObject> responseEntity= RestTemplateUtil.get(url, JSONObject.class,map);

        return StringUtil.json2ResponseResult(responseEntity.getBody().toString(),UserReadableVo.class);
    }

    /**
     * logout
     * @author WangGang
     * @date 2021/10/29
     */
    @GetMapping("logout")
    public ResponseResult<String> logout(){
        HttpHeaders headers = new HttpHeaders();
        headers.add("charset", "UTF-8");
        headers.add("token",propertyConfig.getUserToken());
        headers.setContentType(MediaType.APPLICATION_JSON);

        String url=propertyConfig.getUserServer()+propertyConfig.getUrlLogout();
        ResponseEntity<JSONObject> responseEntity= RestTemplateUtil.get(url, headers,JSONObject.class);

        return StringUtil.json2ResponseResult(responseEntity.getBody().toString(),String.class);
    }

    /**
     * register
     * @author WangGang
     * @date 2021/11/2
     */
    @PostMapping("register")
    public ResponseResult<String> register(@RequestBody UserRegisterVo registerVo) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("token",propertyConfig.getUserToken());
        // 封装参数和头信息
        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(registerVo),httpHeaders);
        String url = propertyConfig.getUserServer()+propertyConfig.getUrlRegister();
        ResponseEntity<JSONObject> responseEntity= RestTemplateUtil.post(url, httpEntity,JSONObject.class);

        return StringUtil.json2ResponseResult(responseEntity.getBody().toString(),String.class);
    }

    /**
     * update user
     * @author WangGang
     * @date 2021/10/27
     */
    @PutMapping("updateUser")
    public ResponseEntity<User> updateUser(@RequestBody User user) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("token","aa11bb22");
        // 封装参数和头信息
        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(user),httpHeaders);
        String url = "http://localhost:8090/server/updateUser";
        return restTemplate.exchange(url, HttpMethod.PUT,httpEntity,User.class);
    }

    /**
     * update user by util
     * @author WangGang
     * @date 2021/10/27
     */
    @PutMapping("updateUserByUtil")
    public ResponseEntity<User> updateUserByUtil(@RequestBody User user) {
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("token","aa11bb22");
        // 封装参数和头信息
        HttpEntity<JSONObject> httpEntity = new HttpEntity(JSON.toJSON(user),httpHeaders);
        String url = "http://localhost:8090/server/updateUser";
        return RestTemplateUtil.put(url, httpEntity,User.class);
    }

    private ResponseEntity<JSONObject> post(String url, LinkedMultiValueMap<String, Object> params) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        HttpEntity<LinkedMultiValueMap<String, Object>> request = new HttpEntity<>(params, headers);
        return restTemplate.postForEntity(url,
                request, JSONObject.class);
    }

    private <T> HufuResponseVo<T> json2HufuResponseVo(String json, Class<T> clazz){
        return JSONObject.parseObject(json, new TypeReference<HufuResponseVo<T>>(clazz) {
        });
    }
}
